home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 2
/
Nebula Two.iso
/
SourceCode
/
Database
/
Evaluator
/
SQLWindow.m
< prev
Wrap
Text File
|
1993-11-01
|
4KB
|
157 lines
/* SQLWindow.m:
* You may freely copy, distribute, and reuse the code in this example.
* NeXT disclaims any warranty of any kind, expressed or implied, as to its
* fitness for any particular use.
*
* Written by Jack Greenfield
*
*/
#import "ScrollViewExtras.h"
#import "SQLWindow.h"
#import "MultiBinder.h"
#define FAILURE NXLocalizedString("Failure:", NULL, \
"Message given to user when an operation has failed.")
#define CANNOT_CONNECT NXLocalizedString("Cannot connect to database", NULL, \
"Message given to user to explain what fails. ")
#define OK NXLocalizedString("OK", NULL, "Okay to continue ")
@implementation SQLWindow
- free
{
[database free];
return [super free];
}
- initWithFile:(const char *)filename
{
char path[MAXPATHLEN];
if ((self = [super init]) != nil)
{
database = [[DBDatabase alloc] initFromFile:filename];
if (![database connect])
{
NXRunAlertPanel(FAILURE, CANNOT_CONNECT, OK, NULL, NULL);
return [self free];
}
[[NXBundle mainBundle] getPath:path forResource:"SQLWindow" ofType:"nib"];
[NXApp loadNibFile:path owner:self withNames:NO];
[[resultsView window] setDelegate:self];
[[resultsView window] setTitleAsFilename:filename];
[[queryView docView] selectAll:self];
[[resultsView window] makeKeyAndOrderFront:self];
}
return self;
}
- database { return database; }
- evaluate:sender
{
int charCount;
char *buffer;
MultiBinder *binder;
List * rowsList;
if ((charCount = [[queryView docView] textLength]) > 0)
{
binder = [[MultiBinder alloc] initFromPropertyLists:nil];
[binder setDatabase:database];
[binder setDelegate:self];
rowsList = [[List alloc] init];
/* This casting is needed to avoid the compiler warning
that List doesn't implement DBContainers protocol
*/
[binder setContainer: (id)rowsList];
buffer = (char *) alloca(1 + charCount);
[[queryView docView] getSubstring:buffer start:0 length:charCount];
buffer[charCount] = 0;
while (charCount > 0 && buffer[--charCount] == '\n')
buffer[charCount] = 0;
[resultsView sprintf:"%s\n", buffer];
if (![binder evaluateString:buffer])
[resultsView sprintf:"EVALUATION FAILED\n\n"];
if (![binder fetch])
[resultsView sprintf:"FETCH FAILED\n\n"];
else
/* For the last result set, binderWillChangeResultSet
* needs to be called explicitly.
*/
[self binderWillChangeResultSet:binder];
[resultsView sprintf:"\n"];
[binder free];
[rowsList free];
}
[[queryView docView] selectText:self];
return self;
}
- clear:sender
{
[resultsView clear:sender];
[[queryView docView] selectText:self];
return self;
}
- print:sender
{
[resultsView print:sender];
[[queryView docView] selectText:self];
return self;
}
/* This delegate method will be called every time a new result set is being
* fetched. All objects returned by the binder fetch can be retrieved from the
* binder container (named rowsList here). Note that the container will get
* flushed everytime a new result set is retrieved. This delegate method is the
* place where you can save the result set elsewhere if needed.
*/
- binderWillChangeResultSet:(MultiBinder *)binder
{
int rowsIndex;
int rowsCount;
int propIndex;
int propCount;
List *rowsList;
List *propList;
propList = [[List alloc] init];
[binder getCurrentProperties:propList];
rowsList = [binder container];
rowsCount = [rowsList count];
[resultsView sprintf:"\nresult set %d\n", [binder currentResultSet]];
[resultsView sprintf:"%u records selected\n", rowsCount];
[binder setFirst];
for (rowsIndex = 0; rowsIndex < rowsCount; ++rowsIndex)
{
propCount = [propList count];
for (propIndex = 0; propIndex < propCount; ++propIndex)
{
id p = [propList objectAt:propIndex];
[resultsView sprintf:"%s=(%s) ",
[p name], [[binder valueForProperty:p] stringValue]];
}
[resultsView sprintf:"\n"];
[binder setNext];
}
[propList free];
return self;
}
@end